/**
  ******************************************************************************
  * @file    mg_driver_ble.h
  * @author  
  * @version V1.0
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2020 Shanghai Macrogiga Electronics</center></h2>
  *
  ******************************************************************************
  */

#ifndef __MG_DRIVER_BLE_H__
#define __MG_DRIVER_BLE_H__

#include "mg_driver_types.h"

//data structure
typedef struct _pdu_hdr_t{
    u8  type;
    u8  len;
} pdu_hdr_t;

typedef struct _txrx_data_state_t{
    u8  stateFlags;
    u8  len0;
    u8  len1;
    u8  rsv;
} txrx_data_state_t;

#define ROLE_NONE   0x00
#define ROLE_SLAVE  0x01
#define ROLE_MASTER 0x02

#define LEN_BLE_ADDR       6

#define ADV_IND_ID              0
#define ADV_SCAN_RSP_ID         1

#define BLE_MODE_ADV_IND              1
#define BLE_MODE_NONCONNECT_ADV       2
#define BLE_MODE_SLAVE_RX             3
#define BLE_MODE_MASTER_SCAN_PASSIVE  4
#define BLE_MODE_MASTER_SCAN_ACTIVE   5
#define BLE_MODE_MASTER_CONN_INIT     6
#define BLE_MODE_MASTER_CONN_TX       7


#define CONFIG                0x00
#define MODE_TYPE             0x01 /*MODE_CFG*/
#define CH_NO                 0x02 /*BLE_CHNL_CTRL*/
#define TIMEOUT_CTRL          0x03
#define WAITTIME_CTRL         0x04
#define PDU_TYPE_CTRL         0x05 /*RF_SETUP ?? */
#define PKT_CTRL              0x06
#define CE_CTRL               0x07
#define DEBUG_CTRL            0x08
#define IC_VER                0x09
#define OTHER                 0x0a
#define TXRX_DATA_STATE       0x0b
#define ADV_HDR_TX0           0x0c /*TX_PDU_HEADER_ADV0*/
#define ADV_HDR_RX0           0x0d /*RX_PDU_HEADER_ADV0*/
#define ADV_HDR_TX1           0x0e /*TX_PDU_HEADER_ADV1*/
#define ADV_HDR_RX1           0x0f /*RX_PDU_HEADER_ADV1*/
#define DATA_HDR_TX0          0x10 /*TX_PDU_HEADER_DATA0*/
#define DATA_HDR_RX0          0x11 /*RX_PDU_HEADER_DATA0*/
#define DATA_HDR_TX1          0x12 /*TX_PDU_HEADER_DATA1*/
//0x13 reserved
#define ADVA_LOCAL_ADDR       0x14
#define BLE_TX_INITA          0x15  /*used in direct IND*/
#define BLE_RX_ADVA_0         0x16
#define BLE_RX_INITA_0        0x17
#define BLE_RX_ADVA_1         0x18  /*used for scan and rsp*/
#define BLE_TX_ACCESS_ADDR    0x19  /*AA*/
#define LONG_PKT_IND_STATE    0x1a
#define BLE_CRC_INIT_DATA     0x1b
#define IRQ_STATE             0x1c
#define LF_COUNTER_REG        0x1d
#define BLE_WAKE_UP_TIME      0x1e  /*wake up interval value*/
#define MOST_LF_COUNTER_VALUE 0x1f

#define DEM_CONTROL_0         0x23
#define DEM_CONTROL           0x24  /*DEM control register*/
#define BSB_CONTROL           0x25

#define XO_CTRL               0x34
#define TSENS                 0x3F

#define CHIP_OK              OTHER
#define RF_SETUP     PDU_TYPE_CTRL

#define IRQ_MASK_WAKEUP       0x10
#define IRQ_MASK_SLEEP        0x20
#define IRQ_MASK_CAL          0x40
#define IRQ_MASK_SEG          0x80
#define IRQ_READ_CLEAR_DISABLE 0x00

#define PDU_TYPE_BIT_ADV_IND          0x01
#define PDU_TYPE_BIT_ADV_DIRECT_IND   0x02
#define PDU_TYPE_BIT_ADV_CONNECT_IND  0x04
#define PDU_TYPE_BIT_ADV_SCAN_REQ     0x08
#define PDU_TYPE_BIT_ADV_SCAN_RSP     0x10
#define PDU_TYPE_BIT_CONNECT_REQ      0x12
#define PDU_TYPE_BIT_ADV_SCAN_IND     0x14

#define DBG_addr_type_check_bit_EN    0x40

#define HDR_TYPE_ADV              0
#define HDR_TYPE_DATA             1

#define R_RX_PAYLOAD0_LEN         0xE0
#define R_RX_PAYLOAD1_LEN         0xE1
#define R_RX_PAYLOAD0             0xE2
#define R_RX_PAYLOAD1             0xE3
#define W_TX_PAYLOAD0             0xE4
#define W_TX_PAYLOAD1             0xE5

#define W_RX_PAYLOAD0             0xE6
#define W_RX_PAYLOAD1             0xE7
#define R_TX_PAYLOAD0             0xE8
#define R_TX_PAYLOAD1             0xE9
#define R_TX_PAYLOADX             0xEA
#define W_TX_PAYLOADX             0xEB

#define IRQ_STATUS_WAKE_UP_BIT    (0x01 << 5)
#define IRQ_STATUS_SLEEP_BIT      (0x02 << 5)
#define IRQ_STATUS_CAL_DONE_BIT   (0x04 << 5)
#define IRQ_STATUS_TX_SEG_BIT       0x10
#define IRQ_STATUS_RX_SEG_BIT       0x08
#define IRQ_LONG_PKT_STATE_TX_SEG   0x80
#define IRQ_LONG_PKT_STATE_RX_SEG   0x40
#define IRQ_LONG_PKT_STATE_SEG_MASK 0xC0
#define IRQ_LONG_PKT_STATE_SEG_TX_FIFO_IND_MASK 0x07


#define TXRX_RX_FAIL_FLAG         0x08  /*rx timeout flag. For CRC error case,DEBUG_CTRL->rx_crc_err = 1*/
#define TXRX_RX_NEW_DATA          0x04
#define TXRX_TX_NEW_DATA          0x02
#define TXRX_TX_FIFO_ID           0x01
#define TXRX_IDLE                 0X00
#define TXRX_RX_TIMEOUT           TXRX_RX_FAIL_FLAG /*rx timeout*/

#define MODE_CONTINUE_TEST_MODE        0x08
#define MODE_WAKEUP_INTERVAL_ENABLE    0x10

#define BLE_ROLE_NONE        0x00
#define BLE_ROLE_MASTER_SCAN 0x01
#define BLE_ROLE_MASTER_CONN 0x02
#define BLE_ROLE_SLAVE       0x03

#define LF_TIME1MS             (32) /* 32kHz */
#define LF_TIME1P25MS          (LF_TIME1MS*5/4)
#define LF_TIME0P625MS         (LF_TIME1P25MS/2)

extern void mg_writeReg(u8 reg, const u8 value);
//void mg_readReg(u8 reg, u8 *value);
extern void mg_writeBuf(u8 reg, u8 const *pBuf, u8 len);
extern void mg_readBuf(u8 reg, u8 *pBuf, u8 len);

void radio_setChannel(u8 channel);
void radio_setAccessCode(u8 *accessCode/*[4]*/);
void radio_setCrcInit(u8 *initVal/*[3]*/);

void radio_setLongPktCfg(u8 delay_us);
void reset_Long_Pkt_Buf_Status(u8 radio_tx_fifo_id/*0/1*/);
//u8 radio_getLongPktState(void);
void long_pkt_rx_tx_init(void);
void long_pkt_rx_tx_reset(void);
u8   radio_seg_tx_start(u8 tx_fifo_idx/*0 or 1*/); //return 0 means error found, start the long pkd tx
void radio_seg_rx_tx_irq(void);

void radio_setTxPayload(u8 PlayloadID/*0/1*/, const u8* dataPtr, u8 dataLen);
void radio_setAdvPayload(u8 ID/*0-ADV_IND_ID/1-ADV_SCAN_RSP_ID*/,u8* advPtr, u8 len);

void radio_setTxDataHeader(u8 DataHeaderID/*0/1*/, pdu_hdr_t pduHdr);
void radio_setAdvHeader(u8 ID/*0-ADV_IND_ID/1-ADV_SCAN_RSP_ID*/,pdu_hdr_t advHdr);

void radio_readIRQ(u8 *status);
void radio_setIrqMask(u8 maskbits); //maskbits can be any combination of {IRQ_MASK_XXX}
void radio_clearIRQ(u8 status);
void radio_getHdr(u8 adv_data, u8 ID/*0/1*/, u8 *ptr);
void radio_getPdu(u8 adv_data, u8 ID, u8 *ptr, u8 *len); /*for long package, it must change to u16 type!!!!*/

void radio_setWakeupTime(u32 lfclk);
void radio_setMode(u8 mode);
void radio_setModeDisable(void);
void radio_setXoPwrDnWait(u8 v);
void radio_setWakeUpSuffix(u8 v);
void radio_setRxTimeout(u32 modeTimeout /*max is 24 bit*/,u32 ContinueTimeOut); /*unit:us*/
void radio_setBleAddr(u8 *addr/*6Bytes*/);
u8*  radio_getBleAddr(void);
void radio_setDirectIndTargetAddr(u8 *addr/*6Bytes*/);
//
//#define TXPWR_0DBM    0x03  /* 0dBm*/
//#define TXPWR__6DBM   0x02  /*-6dBm*/
//#define TXPWR__12DBM  0x01  /*-12dBm*/
//#define TXPWR__18DBM  0x00  /*-18dBm*/
//void radio_setPaGain(u8 txpwr);
u8 radio_initBle(u8 txpwr, u8**addr);

void radio_setWaitTime(u32 TxWait, u32 RxWait);  /*unit:us*/
void radio_setWakeupTimeout(u32 modeTimeout/*unit lf-clk*/);
void radio_getTxRxState(txrx_data_state_t *state);
void readio_setAdvPudTypeFilter(u8 filter); /*1 means enabled reception*/

void radio_setWakeupNow(void); //wakeup right now
void radio_setInterval(u32 lfclk); //set BB auto wakeup interval
void radio_setIntervalTestMode(u32 us/*us*/); //for direct test mode
void radio_setIntervalDisabled(void); //disable interval
u8* radio_get_dbg_info(void);
void radio_setXoPowerDown(void);
void radio_setXoPowerUp(void);
void radio_setBbStandbyMode(void);//set BB goto standby mode(BB power off included)

u8 bb_getSlaveConnState(void);
void bb_setSlaveDisConnect(void);

void radio_startAdv(void);
void radio_stopAdv(void);

u8 radio_getRssi(void);

void Init_HW_Spi(void);

#endif
